home *** CD-ROM | disk | FTP | other *** search
/ The AGA Experience 3 / AGA Experience Volume 3 (1997)(NFA - SAdENESS)[!].iso / software / utilities / graphics / raylab / source / platform / amiga / display.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-16  |  28.8 KB  |  1,033 lines

  1. /*
  2.     name:    display.c
  3.  
  4.     Amiga display routines
  5.     ----------------------
  6.  
  7.     I know there is alot of code in this source, but I have tried
  8.     to make it as flexible as possible, and as Amiga-like as
  9.     possible (with requesters and menus).
  10.  
  11.     Currently supported displaymodes:
  12.  
  13.     0 - No display (default)
  14.     1 - Select from requester
  15.     2 - Greyscale (16 colors), hires, interlaced
  16.     3 - HAM6, lowres, non-interlaced
  17.     4 - HAM6, lowres, interlaced
  18.     5 - HAM8, lowres, non-interlaced
  19.     6 - HAM8, lowres, interlaced
  20.     7 - HAM8, hires, non-interlaced
  21.     8 - HAM8, hires, interlaced
  22.  
  23.  
  24.     This source-code is part of the RayLab 1.1 package, and it is provided
  25.     for your compiling pleasure.  You may use it, change it, re-compile it
  26.     etc., as long as nobody else but you receive the changes/compilations
  27.     that you have made!
  28.  
  29.     You may not use any part(s) of this source-code for your own productions
  30.     without the permission from the author of RayLab. Please read the legal
  31.     information found in the users documentation for RayLab for more details.
  32.  
  33. */
  34.  
  35.  
  36. #include  <exec/libraries.h>        /* AmigaOS specific includes */
  37. #include  <exec/ports.h>
  38. #include  <dos/dos.h>
  39. #include  <intuition/intuition.h>
  40. #include  <graphics/gfxbase.h>
  41. #include  <graphics/modeid.h>
  42. #include  <libraries/asl.h>
  43. #include  <utility/tagitem.h>
  44.  
  45. #include  <proto/exec.h>        /* AmigaOS prototypes */
  46. #include  <proto/intuition.h>
  47. #include  <proto/graphics.h>
  48. #include  <proto/diskfont.h>
  49. #include  <proto/asl.h>
  50.  
  51. #include  "defs.h"
  52. #include  "extern.h"
  53. #include  "amidefs.h"
  54.  
  55.  
  56. struct MyDisplayInfo {            /* Used for requester */
  57.     ULONG    ModeID;
  58.     UWORD    Depth;
  59.     BOOL    AutoScroll;
  60. };
  61.  
  62.  
  63. /* Prototypes for some subroutines */
  64.  
  65. void OpenAmigaScreen(struct NewScreen *SPars,ULONG *STags,struct NewWindow *WPars,ULONG *WTags,UBYTE *Palette,ULONG NumCols);
  66. void CloseAmigaScreen(void);
  67. UBYTE ConvertColorToHam6(COLOR24 *RGBColor, int x, int y);
  68. UBYTE ConvertColorToGrey(COLOR24 *RGBColor, int x, int y);
  69. UBYTE ConvertColorToHam8(COLOR24 *RGBColor, int x, int y);
  70. UBYTE MG_DitherGrey(UBYTE Value, int x, int y);
  71. UBYTE MG_Dither8(UBYTE Value, int x, int y);
  72. void MG_Dither24(COLOR12 *RGBColor12, COLOR24 *RGBColor24, int x, int y);
  73. void RequestDisplay(struct MyDisplayInfo *mydisplayinfo);
  74.  
  75.  
  76. /* Some declarations */
  77.  
  78. #define DISPLAY_NONE       0        /* Supported display modes */
  79. #define DISPLAY_REQUEST    1
  80. #define DISPLAY_GREY       2
  81. #define DISPLAY_HAM6       3
  82. #define DISPLAY_HAM6LACE   4
  83. #define DISPLAY_HAM8       5
  84. #define DISPLAY_HAM8LACE   6
  85. #define DISPLAY_HAM8HI     7
  86. #define DISPLAY_HAM8HILACE 8
  87. #define DISPLAY_LAST       DISPLAY_HAM8HILACE
  88.  
  89. #define DMODE_GREY  1
  90. #define DMODE_HAM   2
  91. #define DMODE_HIRES 4        /* Indicates "high" x-resolution */
  92. #define DMODE_LACE  8        /* Indicates "high" y-resolution */
  93. #define DMODE_TRUEC 16        /* True-color, not supported yet */
  94.  
  95. #define HAM_MOD_PAL 0x00
  96. #define HAM_MOD_RED 0x20
  97. #define HAM_MOD_GRN 0x30
  98. #define HAM_MOD_BLU 0x10
  99.  
  100. #define HAM8_MOD_PAL 0x00
  101. #define HAM8_MOD_BLU 0x40
  102. #define HAM8_MOD_RED 0x80
  103. #define HAM8_MOD_GRN 0xC0
  104.  
  105. #define SCREEN_TITLE_HEIGHT 20        /* Should not be needed... */
  106.  
  107.  
  108. /* Some global variables */
  109.  
  110.     extern int    Language;
  111.     extern char    **MyCatalogs[];
  112.     int    CurrentDisplayType;
  113.     COLOR12    Last12BitColor = {0,0,0};
  114.     COLOR24    Last24BitColor = {0,0,0};
  115.     long    DisplayFlags,DisplayDepth,PaletteColors;
  116.  
  117.     struct    Screen *RL_Screen = NULL;
  118.     struct    Window *RL_Window = NULL;
  119.     struct    RastPort *RL_RastPort = NULL;
  120.     struct    ViewPort *RL_ViewPort = NULL;
  121.     struct    IntuitionBase *IntuitionBase = NULL;
  122.     struct    GfxBase *GfxBase = NULL;
  123.     struct    Library *DiskfontBase = NULL;
  124.     struct    Library *AslBase = NULL;
  125.  
  126.     /* The best HAM6-palette i could come up with: */
  127.  
  128.     UBYTE    Ham6Palette[] = {
  129.             0x00,0x00,0x00, 0xAA,0xAA,0xAA,
  130.             0x55,0x55,0x55, 0xFF,0xFF,0xFF,
  131.             0x88,0x00,0x88, 0xFF,0x44,0xAA,
  132.             0xEE,0x00,0x00, 0x66,0x22,0x00,
  133.             0xFF,0x66,0x00, 0xFF,0xAA,0x88,
  134.             0xFF,0xEE,0x00, 0x00,0x88,0x00,
  135.             0x00,0xDD,0x00, 0x00,0xCC,0xCC,
  136.             0x00,0x66,0xFF, 0x00,0x00,0xAA,    /* 16 cols */
  137.         };
  138.  
  139.     /* The best HAM8-palette i could come up with (?): */
  140.  
  141.     UBYTE    Ham8Palette[] = {
  142.             0x00,0x00,0x00, 0xAA,0xAA,0xAA,
  143.             0x55,0x55,0x55, 0xFF,0xFF,0xFF,
  144.             0x88,0x00,0x88, 0xFF,0x44,0xAA,
  145.             0xEE,0x00,0x00, 0x66,0x22,0x00,
  146.             0xFF,0x66,0x00, 0xFF,0xAA,0x88,
  147.             0xFF,0xEE,0x00, 0x00,0x88,0x00,
  148.             0x00,0xDD,0x00, 0x00,0xCC,0xCC,
  149.             0x00,0x66,0xFF, 0x00,0x00,0xAA,    /* 16 cols */
  150.             0x01,0x23,0x45, 0x67,0x89,0xAB,
  151.             0xCD,0xEF,0xFE, 0xFE,0xDC,0xBA,
  152.             0x98,0x76,0x54, 0x32,0x10,0x01,
  153.             0x23,0x01,0x45, 0x89,0x67,0xAB,
  154.             0xEF,0xCD,0xFE, 0xDC,0xFE,0xBA,
  155.             0x76,0x98,0x54, 0x01,0x32,0x10,
  156.             0x45,0x01,0x23, 0xAB,0x67,0x89,
  157.             0xFE,0xCD,0xEF, 0xBA,0xFE,0xDC,    /* 32 cols */
  158.             0x54,0x98,0x76, 0x01,0x32,0x10,
  159.             0x00,0x00,0x55, 0x00,0x00,0xAA,
  160.             0x00,0x00,0xFF, 0x00,0x55,0x00,
  161.             0x00,0x55,0x55, 0x00,0x55,0xAA,
  162.             0x00,0x55,0xFF, 0x00,0xAA,0x00,
  163.             0x00,0xAA,0x55, 0x00,0xAA,0xAA,
  164.             0x00,0xAA,0xFF, 0x00,0xFF,0x00,
  165.             0x00,0xFF,0x55, 0x00,0xFF,0xAA,    /* 48 cols */
  166.             0x00,0xFF,0xFF, 0x55,0x00,0x00,
  167.             0x55,0x00,0x55, 0x55,0x00,0xAA,
  168.             0x55,0x00,0xFF, 0x55,0x55,0x00,
  169.             0x55,0x55,0x55, 0x55,0x55,0xAA,
  170.             0x55,0x55,0xFF, 0x55,0xAA,0x00,
  171.             0x55,0xAA,0x55, 0x55,0xAA,0xAA,
  172.             0x55,0xAA,0xFF, 0x55,0xFF,0x00,
  173.             0x55,0xFF,0x55, 0x55,0xFF,0xAA,    /* 64 cols */
  174.         };
  175.  
  176.  
  177.     UWORD    DitherMask[16] = {
  178.             0x8000, 0x8080, 0x8410, 0x8888,
  179.             0x9224, 0xA492, 0xA94A, 0xAAAA,
  180.             0xD555, 0xD6B5, 0xDB6D, 0xEDDB,
  181.             0xF777, 0xFBEF, 0xFF7F, 0xFFFF
  182.         };
  183.  
  184.     UBYTE    DitherYTable[16] = {
  185.             0x08, 0x0B, 0x0E, 0x0F, 0x10, 0x0F, 0x0E, 0x0B,
  186.             0x08, 0x05, 0x02, 0x01, 0x00, 0x01, 0x02, 0x05
  187.         };
  188.  
  189.     struct TextAttr TopazAttr =
  190.         {(STRPTR)"topaz.font",TOPAZ_EIGHTY,0,0};
  191.  
  192.     struct TextAttr GraniteAttr =
  193.         {(STRPTR)"Granite.font",12,0,0};    /* Lores */
  194.  
  195.     struct TextAttr HelveticaAttr =
  196.         {(STRPTR)"helvetica.font",11,0,0};    /* Lores */
  197.  
  198.     struct TextAttr OpalAttr =
  199.         {(STRPTR)"opal.font",12,0,0};        /* Hires */
  200.  
  201.  
  202.     extern int    spenttime, spent_h, spent_m, spent_s;
  203.  
  204.  
  205. /******************************************************************
  206.  *
  207.  *  AvailableDisplayModes()
  208.  *
  209.  ******************************************************************/
  210.  
  211. void AvailableDisplayModes(void)
  212. {
  213.     fprintf(textoutput,MyCatalogs[Language][CTXT_AVAILDISP]);
  214.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP0]);
  215.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP1]);
  216.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP2]);
  217.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP3]);
  218.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP4]);
  219.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP5]);
  220.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP6]);
  221.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP7]);
  222.     fprintf(textoutput,MyCatalogs[Language][CTXT_DISP8]);
  223. }
  224.  
  225.  
  226. /******************************************************************
  227.  *
  228.  *  OpenDisplay()
  229.  *
  230.  ******************************************************************/
  231.  
  232. long OpenDisplay(long DisplayType)
  233. {
  234.     long    ModeID, AutoScroll;
  235.     UBYTE    *PalettePtr;
  236.     struct MyDisplayInfo mydisplayinfo;
  237.     struct DisplayInfo displayinfo;
  238.     long    Ret_OK;
  239.  
  240.     ULONG ScreenTagList[] =
  241.     {
  242.         SA_DisplayID,0,
  243.         SA_AutoScroll,1,
  244.         SA_Overscan,OSCAN_MAX,
  245.         TAG_DONE,0
  246.     };
  247.  
  248.     ULONG WindowTagList[] =
  249.     {
  250.         WA_NewLookMenus,1,        /* Intuition TRUE = 1 */
  251.         TAG_DONE,0
  252.     };
  253.  
  254.     struct NewScreen ScreenPars =
  255.     {
  256.         0, 0,        /* LeftEdge, TopEdge        */
  257.         NULL, NULL,    /* Set screen size later    */
  258.         NULL,        /* Set depth later          */
  259.         2, 7,        /* DetailPen, BlockPen      */
  260.         NULL,        /* Set display-mode later   */
  261.         CUSTOMSCREEN,
  262.         NULL,        /* Set font later           */
  263.         NULL,        /* Set title later          */
  264.         NULL,        /* No special gadgets       */
  265.         NULL        /* No custom bitmap         */
  266.     };
  267.  
  268.     struct NewWindow WindowPars =
  269.     {
  270.         0, 0,        /* LeftEdge, TopEdge        */
  271.         NULL, NULL,    /* Set screen size later    */
  272.         3, 7,        /* DetailPen, BlockPen      */
  273.         MENUPICK,    /* IDCMP                    */
  274.         SMART_REFRESH | BORDERLESS | NOCAREREFRESH,
  275.         NULL,        /* No special gadgets       */
  276.         NULL,        /* No checkmark             */
  277.         NULL,        /* No window title          */
  278.         NULL,        /* Set screen later         */
  279.         NULL,        /* No bitmap                */
  280.         NULL, NULL,    /* Set min size later       */
  281.         NULL, NULL,    /* Set max size later       */
  282.         CUSTOMSCREEN
  283.     };
  284.  
  285.  
  286.     RL_Screen = NULL; RL_Window = NULL;
  287.  
  288.     IntuitionBase = (struct IntuitionBase *)
  289.         OpenLibrary("intuition.library",36);
  290.  
  291.     if(IntuitionBase==NULL) {
  292.         fprintf(textoutput,MyCatalogs[Language][CTXT_INTERR]);
  293.         IntuitionBase = NULL;
  294.     }
  295.     else {
  296.         GfxBase = (struct GfxBase *)
  297.             OpenLibrary("graphics.library",36);
  298.         if(GfxBase==NULL) {
  299.             fprintf(textoutput,MyCatalogs[Language][CTXT_GFXERR]);
  300.             CloseLibrary((struct Library *)IntuitionBase);
  301.             IntuitionBase = NULL; GfxBase = NULL;
  302.         }
  303.     }
  304.  
  305.     if( (IntuitionBase!=NULL) && (GfxBase!=NULL) ) {
  306.         if( (DisplayType>DISPLAY_NONE) && (DisplayType<=DISPLAY_LAST) ) {
  307.         CurrentDisplayType = DisplayType;
  308.  
  309.         ScreenPars.Width = (WORD)PicWidth;
  310.         ScreenPars.Height = (WORD)PicHeight;
  311.         ScreenPars.DefaultTitle = MyCatalogs[Language][CTXT_DISPTITLE];
  312.  
  313.         WindowPars.Width = (WORD)PicWidth;
  314.         WindowPars.Height = (WORD)PicHeight;
  315.         WindowPars.MinWidth = WindowPars.MaxWidth = (WORD)PicWidth;
  316.         WindowPars.MinHeight = WindowPars.MaxHeight = (WORD)PicHeight;
  317.  
  318.         ScreenTagList[1]=DEFAULT_MONITOR_ID;    /* MONITOR_ID_MASK */
  319.  
  320.         ModeID=0L; AutoScroll=1L;
  321.         DisplayFlags=0L;
  322.         DisplayDepth=0L;
  323.         PaletteColors=0L;
  324.         PalettePtr=NULL;
  325.  
  326.         switch(CurrentDisplayType) {
  327.             case DISPLAY_GREY:
  328.             ModeID=HIRESLACE_KEY;
  329.             DisplayFlags=DMODE_GREY|DMODE_HIRES|DMODE_LACE;
  330.             DisplayDepth=4;
  331.             PaletteColors=16;
  332.             break;
  333.  
  334.             case DISPLAY_HAM6:
  335.             ModeID=HAM_KEY;
  336.             DisplayFlags=DMODE_HAM;
  337.             DisplayDepth=6;
  338.             PaletteColors=16;
  339.             PalettePtr=Ham6Palette;
  340.             break;
  341.  
  342.             case DISPLAY_HAM6LACE:
  343.             ModeID=HAMLACE_KEY;
  344.             DisplayFlags=DMODE_HAM|DMODE_LACE;
  345.             DisplayDepth=6;
  346.             PaletteColors=16;
  347.             PalettePtr=Ham6Palette;
  348.             break;
  349.  
  350.             case DISPLAY_HAM8:
  351.             ModeID=HAM_KEY;
  352.             DisplayFlags=DMODE_HAM;
  353.             DisplayDepth=8;
  354.             PaletteColors=64;
  355.             PalettePtr=Ham8Palette;
  356.             break;
  357.  
  358.             case DISPLAY_HAM8LACE:
  359.             ModeID=HAMLACE_KEY;
  360.             DisplayFlags=DMODE_HAM|DMODE_LACE;
  361.             DisplayDepth=8;
  362.             PaletteColors=64;
  363.             PalettePtr=Ham8Palette;
  364.             break;
  365.  
  366.             case DISPLAY_HAM8HI:
  367.             ModeID=HIRESHAM_KEY;
  368.             DisplayFlags=DMODE_HAM|DMODE_HIRES;
  369.             DisplayDepth=8;
  370.             PaletteColors=64;
  371.             PalettePtr=Ham8Palette;
  372.             break;
  373.  
  374.             case DISPLAY_HAM8HILACE:
  375.             ModeID=HIRESHAMLACE_KEY;
  376.             DisplayFlags=DMODE_HAM|DMODE_HIRES|DMODE_LACE;
  377.             DisplayDepth=8;
  378.             PaletteColors=64;
  379.             PalettePtr=Ham8Palette;
  380.             break;
  381.  
  382.             case DISPLAY_REQUEST:
  383.             RequestDisplay(&mydisplayinfo);
  384.             ModeID=mydisplayinfo.ModeID;
  385.             AutoScroll=mydisplayinfo.AutoScroll;
  386.             DisplayDepth=(ULONG)mydisplayinfo.Depth;
  387.             DisplayFlags=0L;
  388.             if(DisplayDepth>8) {
  389.                 DisplayFlags=DMODE_TRUEC;
  390.                 fprintf(textoutput,MyCatalogs[Language][CTXT_TRUECNSUPP]);
  391.                 CurrentDisplayType=DISPLAY_NONE;
  392.             }
  393.             else if(GfxBase->LibNode.lib_Version>=36) {
  394.                 if(GetDisplayInfoData(NULL,(UBYTE *)&displayinfo,sizeof(struct DisplayInfo),DTAG_DISP,ModeID)) {
  395.                 if(displayinfo.Resolution.x<30)
  396.                     DisplayFlags=DisplayFlags|DMODE_HIRES;
  397.                 if(((displayinfo.PropertyFlags&DIPF_IS_LACE)!=0)||(displayinfo.Resolution.y<30))
  398.                     DisplayFlags=DisplayFlags|DMODE_LACE;
  399.                 if((displayinfo.PropertyFlags&DIPF_IS_HAM)!=0) {
  400.                     DisplayFlags=DisplayFlags|DMODE_HAM;
  401.                     PaletteColors=1L<<(DisplayDepth-2);
  402.                     if(DisplayDepth==6)
  403.                     PalettePtr=Ham6Palette;
  404.                     else
  405.                     PalettePtr=Ham8Palette;
  406.                 }
  407.                 else {
  408.                     DisplayFlags=DisplayFlags|DMODE_GREY;
  409.                     PaletteColors=1L<<DisplayDepth;
  410.                 }
  411.                 }
  412.             }
  413.             if(DisplayFlags==0L) {
  414.                 DisplayFlags=DMODE_GREY;
  415.                 PaletteColors=1L<<DisplayDepth;
  416.             }
  417.             break;
  418.  
  419.             case DISPLAY_NONE:
  420.             default:
  421.             ModeID=0;
  422.             DisplayFlags=0;
  423.             DisplayDepth=0;
  424.             CurrentDisplayType=DISPLAY_NONE;
  425.             break;
  426.         }
  427.  
  428.  
  429.     /* Setup screen, knowing the display modes... */
  430.  
  431.         if(CurrentDisplayType!=DISPLAY_NONE) {
  432.             ScreenTagList[1]=ModeID;
  433.             ScreenTagList[3]=AutoScroll;
  434.             ScreenPars.Depth=DisplayDepth;
  435.  
  436.             if((DisplayFlags&DMODE_HAM)!=0L) {
  437.             ScreenPars.DetailPen = 3;
  438.             ScreenPars.BlockPen = 1;
  439.             }
  440.             else {
  441.             ScreenPars.DetailPen = (2*PaletteColors)/16;
  442.             ScreenPars.BlockPen = (7*PaletteColors)/16;
  443.             }
  444.  
  445.             if(((DisplayFlags&DMODE_HIRES)!=0L)&&((DisplayFlags&DMODE_LACE)!=0L))
  446.             ScreenPars.Font = &OpalAttr;
  447.             else if((DisplayFlags&DMODE_HIRES)!=0L)
  448.             ScreenPars.Font = &OpalAttr;
  449.             else if((DisplayFlags&DMODE_LACE)!=0L)
  450.             ScreenPars.Font = &GraniteAttr;
  451.             else
  452.             ScreenPars.Font = &HelveticaAttr;
  453.  
  454.             OpenAmigaScreen(&ScreenPars,ScreenTagList,&WindowPars,WindowTagList,PalettePtr,(ULONG)PaletteColors);
  455.         }
  456.         else {
  457.             fprintf(textoutput,MyCatalogs[Language][CTXT_UNSUPP],DisplayType);
  458.         }
  459.         }
  460.         else {
  461.         if(DisplayType!=DISPLAY_NONE)
  462.             fprintf(textoutput,MyCatalogs[Language][CTXT_UNSUPP],DisplayType);
  463.         CurrentDisplayType = DISPLAY_NONE;
  464.         }
  465.     }
  466.     else {
  467.         CurrentDisplayType = DISPLAY_NONE;
  468.     }
  469.  
  470.     Ret_OK = 0L;
  471.     if(CurrentDisplayType!=DISPLAY_NONE) {
  472.         Ret_OK = 1L;
  473.     }
  474.  
  475.     return(Ret_OK);
  476. }
  477.  
  478.  
  479. /******************************************************************
  480.  *
  481.  *  CloseDisplay()
  482.  *
  483.  ******************************************************************/
  484.  
  485. void CloseDisplay(void)
  486. {
  487.     ULONG    signalmask, signals, class, code, menunum, itemnum;
  488.     struct    IntuiMessage *message;
  489.     int    done;
  490.  
  491.     if((CurrentDisplayType!=0)&&(picturerendering==TRUE)) {
  492.         CloseAmigaScreen();
  493.     }
  494.     else if((CurrentDisplayType!=0)&&(picturerendering==FALSE)) {
  495.         struct IntuiText ItemsText[] =
  496.         {
  497.         {2,1,JAM1,2,1,NULL,NULL,    NULL},
  498.         {2,1,JAM1,2,1,NULL,NULL,    NULL}
  499.         };
  500.  
  501.         struct MenuItem Items[] =
  502.         {
  503.         {
  504.         NULL,        /* No more items            */
  505.         2, 1, 110, 10,    /* Left, top, width, height */
  506.         ITEMTEXT | COMMSEQ | HIGHCOMP,
  507.         0,        /* MutualExclude            */
  508.         NULL,        /* Set item text later      */
  509.         NULL,
  510.         'A',        /* Key equivalent           */
  511.         NULL,        /* Sub item                 */
  512.         MENUNULL    /* NextSelect               */
  513.         },
  514.         {
  515.         NULL,        /* No more items            */
  516.         2, 11, 110, 10,    /* Left, top, width, height */
  517.         ITEMTEXT | COMMSEQ | ITEMENABLED | HIGHCOMP,
  518.         0,        /* MutualExclude            */
  519.         NULL,        /* Set item text later      */
  520.         NULL,
  521.         'C',        /* Key equivalent           */
  522.         NULL,        /* Sub item                 */
  523.         MENUNULL    /* NextSelect               */
  524.         }
  525.  
  526.         };
  527.  
  528.         struct Menu MenuPars =
  529.         {
  530.         NULL,        /* No more menus            */
  531.         0, 0, 120, 40,    /* Left, top, width, height */
  532.         MENUENABLED,    /* Flags                    */
  533.         NULL,        /* Menu name                */
  534.         NULL        /* Set first item later     */
  535.         };
  536.  
  537.         ScreenToFront(RL_Screen);    /* Bring screen to front when done */
  538.         DisplayBeep(RL_Screen);    /* Beep to show that we are done */
  539.         ActivateWindow(RL_Window);    /* Activate window -> menu-access */
  540.  
  541.         ItemsText[0].IText = MyCatalogs[Language][CTXT_ABOUT];
  542.         ItemsText[1].IText = MyCatalogs[Language][CTXT_CLOSE];
  543.         ItemsText[0].ITextFont = ItemsText[1].ITextFont = &TopazAttr;
  544.         Items[0].ItemFill = &ItemsText[0];
  545.         Items[1].ItemFill = &ItemsText[1];
  546.         Items[0].NextItem = &Items[1];
  547.         MenuPars.FirstItem = &Items[0];
  548.         MenuPars.MenuName = MyCatalogs[Language][CTXT_MENU];
  549.  
  550.         SetMenuStrip(RL_Window, &MenuPars);    /* Add menu */
  551.  
  552.         signalmask = 1L << RL_Window->UserPort->mp_SigBit;
  553.         done = FALSE;
  554.  
  555.     /*  Wait for menu select */
  556.  
  557.         while( done == FALSE ) {
  558.         signals = Wait(signalmask);
  559.         if((signals&signalmask)!=0L) {
  560.             while( message = (struct IntuiMessage *)GetMsg(RL_Window->UserPort) ) {
  561.             class = message->Class;
  562.             code = message->Code;
  563.             ReplyMsg((struct Message *)message);
  564.             if(class==MENUPICK) {
  565.                 menunum = MENUNUM(code);
  566.                 itemnum = ITEMNUM(code);
  567.                 if(menunum==0L) {
  568.                 if(itemnum==0L) {
  569.                     DisplayBeep(RL_Screen);
  570.                 }
  571.                 else if(itemnum==1L) {
  572.                     done = TRUE;
  573.                 }
  574.                 }
  575.             }
  576.             }
  577.         }
  578.         }
  579.         CloseAmigaScreen();
  580.     }
  581. }
  582.  
  583.  
  584. /******************************************************************
  585.  *
  586.  *  DisplayPlot()
  587.  *
  588.  ******************************************************************/
  589.  
  590. void DisplayPlot(int x, int y, COLOR24 *RGBColor)
  591. {
  592.     if(CurrentDisplayType!=DISPLAY_NONE) {
  593.         if((DisplayFlags&DMODE_GREY)!=0L)
  594.         SetAPen(RL_RastPort, ConvertColorToGrey(RGBColor,x,y));
  595.         else if(((DisplayFlags&DMODE_HAM)!=0L)&&(DisplayDepth==6))
  596.         SetAPen(RL_RastPort, ConvertColorToHam6(RGBColor,x,y));
  597.         else if(((DisplayFlags&DMODE_HAM)!=0L)&&(DisplayDepth==8))
  598.         SetAPen(RL_RastPort, ConvertColorToHam8(RGBColor,x,y));
  599.         else SetAPen(RL_RastPort,(x+y)&(PaletteColors-1));
  600.         (void) WritePixel(RL_RastPort,x,y);
  601.     }
  602. }
  603.  
  604.  
  605. /******************************************************************
  606.  
  607.     Some routines for converting 24-bit rgb colors to apropriate
  608.     display-modes
  609.  
  610.  ******************************************************************/
  611.  
  612.  
  613. /***************************************************************
  614.  *
  615.  *    ConvertColorToGrey()
  616.  *
  617.  *    Now supports 2-256 colors
  618.  *    (<256 colors: dither, 256 colors: don't)
  619.  *
  620.  ***************************************************************/
  621.  
  622. UBYTE ConvertColorToGrey(COLOR24 *RGBColor, int x, int y)
  623. {
  624.     UBYTE    Grey;
  625.  
  626.     Grey = (UBYTE)(((UWORD)RGBColor->r+(UWORD)RGBColor->g+(UWORD)RGBColor->b)/(UWORD)3);
  627.     if(PaletteColors<256)
  628.         Grey = (UBYTE)MG_DitherGrey(Grey,x,y);
  629.  
  630.     return(Grey);
  631. }
  632.  
  633.  
  634. /***************************************************************
  635.  *
  636.  *    ConvertColorToHam6()
  637.  *
  638.  ***************************************************************/
  639.  
  640. UBYTE ConvertColorToHam6(COLOR24 *RGBColor, int x, int y)
  641. {
  642.     COLOR12    New12BitColor;
  643.     UBYTE    HamMode, HamCol;
  644.     long    Diff12BitColor[3];
  645.     register long RGBDiff, t1, t2, t3, i, BestColor;
  646.  
  647.     if(x==0) {
  648.         Last12BitColor.r = (Ham6Palette[0]>>4)&0x0f;
  649.         Last12BitColor.g = (Ham6Palette[1]>>4)&0x0f;
  650.         Last12BitColor.b = (Ham6Palette[2]>>4)&0x0f;
  651.     }
  652.  
  653.     MG_Dither24(&New12BitColor,RGBColor,x,y);    /* Dither 24bit -> 12bit */
  654.  
  655.     Diff12BitColor[0] = (long)New12BitColor.r-(long)Last12BitColor.r;
  656.     Diff12BitColor[1] = (long)New12BitColor.g-(long)Last12BitColor.g;
  657.     Diff12BitColor[2] = (long)New12BitColor.b-(long)Last12BitColor.b;
  658.     Diff12BitColor[0] *= Diff12BitColor[0];
  659.     Diff12BitColor[1] *= Diff12BitColor[1];
  660.     Diff12BitColor[2] *= Diff12BitColor[2];
  661.     HamMode = HAM_MOD_RED;
  662.     if(Diff12BitColor[1]>Diff12BitColor[0]) {
  663.         HamMode = HAM_MOD_GRN;
  664.         if(Diff12BitColor[2]>Diff12BitColor[1]) {
  665.             HamMode = HAM_MOD_BLU;
  666.         }
  667.     }
  668.     else if(Diff12BitColor[2]>Diff12BitColor[0]) {
  669.         HamMode = HAM_MOD_BLU;
  670.     }
  671.  
  672.     switch(HamMode) {
  673.         case HAM_MOD_RED:
  674.         HamCol = Last12BitColor.r = New12BitColor.r;
  675.         RGBDiff = Diff12BitColor[1] + Diff12BitColor[2];
  676.         break;
  677.         case HAM_MOD_GRN:
  678.         HamCol = Last12BitColor.g = New12BitColor.g;
  679.         RGBDiff = Diff12BitColor[0] + Diff12BitColor[2];
  680.         break;
  681.         case HAM_MOD_BLU:
  682.         HamCol = Last12BitColor.b = New12BitColor.b;
  683.         RGBDiff = Diff12BitColor[0] + Diff12BitColor[1];
  684.         break;
  685.     }
  686.  
  687.     BestColor = 100;
  688.     for(i=0;i<16;i++) {
  689.         t1 = (long)((Ham6Palette[i*3]>>4)&0x0f);
  690.         t1 = t1 - (long)New12BitColor.r;
  691.         t2 = (long)((Ham6Palette[i*3+1]>>4)&0x0f);
  692.         t2 = t2 - (long)New12BitColor.g;
  693.         t3 = (long)((Ham6Palette[i*3+2]>>4)&0x0f);
  694.         t3 = t3 - (long)New12BitColor.b;
  695.         t1 = t1*t1 + t2*t2 + t3*t3;
  696.         if(RGBDiff>t1) {
  697.             RGBDiff = t1;
  698.             BestColor = i;
  699.         }
  700.     }
  701.     if(BestColor<16) {
  702.         HamMode = HAM_MOD_PAL;
  703.         HamCol  = (UBYTE)BestColor;
  704.         Last12BitColor.r = (Ham6Palette[BestColor*3]>>4)&0x0f;
  705.         Last12BitColor.g = (Ham6Palette[BestColor*3+1]>>4)&0x0f;
  706.         Last12BitColor.b = (Ham6Palette[BestColor*3+2]>>4)&0x0f;
  707.     }
  708.  
  709.     return((UBYTE)(HamMode | (HamCol&0x0f)));
  710. }
  711.  
  712.  
  713. /***************************************************************
  714.  *
  715.  *    ConvertColorToHam8()
  716.  *
  717.  ***************************************************************/
  718.  
  719. UBYTE ConvertColorToHam8(COLOR24 *RGBColor, int x, int y)
  720. {
  721.     COLOR24    New24BitColor;
  722.     UBYTE    HamMode, HamCol;
  723.     long    Diff24BitColor[3];
  724.     register long RGBDiff, t1, t2, t3, i, BestColor;
  725.  
  726.     if(x==0) {
  727.         Last24BitColor.r = Ham8Palette[0];
  728.         Last24BitColor.g = Ham8Palette[1];
  729.         Last24BitColor.b = Ham8Palette[2];
  730.     }
  731.  
  732.     New24BitColor=*RGBColor;    /* No dithering */
  733.  
  734.     Diff24BitColor[0] = (long)New24BitColor.r-(long)Last24BitColor.r;
  735.     Diff24BitColor[1] = (long)New24BitColor.g-(long)Last24BitColor.g;
  736.     Diff24BitColor[2] = (long)New24BitColor.b-(long)Last24BitColor.b;
  737.     Diff24BitColor[0] *= Diff24BitColor[0];
  738.     Diff24BitColor[1] *= Diff24BitColor[1];
  739.     Diff24BitColor[2] *= Diff24BitColor[2];
  740.     HamMode = HAM8_MOD_RED;
  741.     if(Diff24BitColor[1]>Diff24BitColor[0]) {
  742.         HamMode = HAM8_MOD_GRN;
  743.         if(Diff24BitColor[2]>Diff24BitColor[1]) {
  744.             HamMode = HAM8_MOD_BLU;
  745.         }
  746.     }
  747.     else if(Diff24BitColor[2]>Diff24BitColor[0]) {
  748.         HamMode = HAM8_MOD_BLU;
  749.     }
  750.  
  751.     switch(HamMode) {
  752.         case HAM8_MOD_RED:
  753.         Last24BitColor.r = (New24BitColor.r&0xfc) | (Last24BitColor.r&0x03);
  754.         HamCol = New24BitColor.r>>2;
  755.         RGBDiff = New24BitColor.r-Last24BitColor.r; RGBDiff*=RGBDiff;
  756.         RGBDiff += Diff24BitColor[1] + Diff24BitColor[2];
  757.         break;
  758.         case HAM8_MOD_GRN:
  759.         Last24BitColor.g = (New24BitColor.g&0xfc) | (Last24BitColor.g&0x03);
  760.         HamCol = New24BitColor.g>>2;
  761.         RGBDiff = New24BitColor.g-Last24BitColor.g; RGBDiff*=RGBDiff;
  762.         RGBDiff += Diff24BitColor[0] + Diff24BitColor[2];
  763.         break;
  764.         case HAM8_MOD_BLU:
  765.         Last24BitColor.b = (New24BitColor.b&0xfc) | (Last24BitColor.b&0x03);
  766.         HamCol = New24BitColor.b>>2;
  767.         RGBDiff = New24BitColor.b-Last24BitColor.b; RGBDiff*=RGBDiff;
  768.         RGBDiff += Diff24BitColor[0] + Diff24BitColor[1];
  769.         break;
  770.     }
  771.  
  772.     BestColor = 100;
  773.     for(i=0;i<192;i+=3) {
  774.         t1 = (long)Ham8Palette[i]   - (long)New24BitColor.r;
  775.         t2 = (long)Ham8Palette[i+1] - (long)New24BitColor.g;
  776.         t3 = (long)Ham8Palette[i+2] - (long)New24BitColor.b;
  777.         t1 = t1*t1 + t2*t2 + t3*t3;
  778.         if(RGBDiff>t1) {
  779.             RGBDiff = t1;
  780.             BestColor = i/3;
  781.         }
  782.     }
  783.     if(BestColor<64) {
  784.         HamMode = HAM8_MOD_PAL;
  785.         HamCol  = (UBYTE)BestColor;
  786.         Last24BitColor.r = (long)Ham8Palette[BestColor*3];
  787.         Last24BitColor.g = (long)Ham8Palette[BestColor*3+1];
  788.         Last24BitColor.b = (long)Ham8Palette[BestColor*3+2];
  789.     }
  790.  
  791.     return((UBYTE)(HamMode | (HamCol & 0x3f)));
  792. }
  793.  
  794.  
  795.  
  796.  
  797. /***************************************************************
  798.  *
  799.  *    This is some strange dithering method that I managed
  800.  *    to produce late one night
  801.  *
  802.  ***************************************************************/
  803.  
  804.  
  805. UBYTE MG_Dither8(UBYTE Value, int x, int y)
  806. {
  807.     UBYTE    Dithered;
  808.  
  809.     Dithered = Value>>4;    /* Make 4-bit value from 8-bit value */
  810.     if(Dithered<15) {
  811.         if(((0x01<<(((y<<2)+x+DitherYTable[y&0x000f])&0x000f))&DitherMask[Value&0x0f])!=0) Dithered++;
  812.     }
  813.     return(Dithered);
  814. }
  815.  
  816.  
  817. UBYTE MG_DitherGrey(UBYTE Value, int x, int y)
  818. {
  819.     UBYTE    Dithered,Val2;
  820.  
  821.     if(DisplayDepth<=4) Val2 = Value>>(4-DisplayDepth);
  822.     else                Val2 = Value<<(DisplayDepth-4);
  823.  
  824.     Dithered = Value>>(8-DisplayDepth);
  825.     if(Dithered<(PaletteColors-1)) {
  826.         if(((0x01<<(((y<<2)+x+DitherYTable[y&0x000f])&0x000f))&DitherMask[Val2&0x0f])!=0) Dithered++;
  827.     }
  828.     return(Dithered);
  829. }
  830.  
  831.  
  832. void MG_Dither24(COLOR12 *RGBColor12, COLOR24 *RGBColor24, int x, int y)
  833. {
  834.     register int    Dither;
  835.  
  836.     RGBColor12->r = (RGBColor24->r>>4)&0x0f;    /* Make 12-bit color from 24-bit color */
  837.     RGBColor12->g = (RGBColor24->g>>4)&0x0f;
  838.     RGBColor12->b = (RGBColor24->b>>4)&0x0f;
  839.     Dither = 0x01<<(((y<<2)+x+DitherYTable[y&0x000f])&0x000f);
  840.     if((RGBColor12->r<15)&(Dither&DitherMask[RGBColor24->r&0x0f])!=0) RGBColor12->r++;
  841.     if((RGBColor12->g<15)&(Dither&DitherMask[RGBColor24->g&0x0f])!=0) RGBColor12->g++;
  842.     if((RGBColor12->b<15)&(Dither&DitherMask[RGBColor24->b&0x0f])!=0) RGBColor12->b++;
  843. }
  844.  
  845.  
  846. /******************************************************************
  847.  
  848.     Some routines for simplifying the opening and closing of Amiga
  849.     screens and windows
  850.  
  851.  ******************************************************************/
  852.  
  853.  
  854. /***************************************************************
  855.  *
  856.  *    OpenAmigaScreen()
  857.  *
  858.  ***************************************************************/
  859.  
  860. void OpenAmigaScreen(struct NewScreen *SPars,ULONG *STags,struct NewWindow *WPars,ULONG *WTags,UBYTE *Palette,ULONG NumCols)
  861. {
  862.     WORD    ScreenHeight,ScreenWidth,ScreenType;
  863.     UBYTE    *Pal8;
  864.     ULONG    ColR,ColG,ColB;
  865.     int    i;
  866.  
  867.     /* Read required font from disk (if necesary) */
  868.     DiskfontBase = OpenLibrary("diskfont.library",36);
  869.     if(DiskfontBase!=NULL) {
  870.         (void) OpenDiskFont(SPars->Font);
  871.         CloseLibrary(DiskfontBase);
  872.     }
  873.  
  874.     /* Determine screen height by briefly opening and closing a dummy screen */
  875.     ScreenWidth=SPars->Width;
  876.     ScreenHeight=SPars->Height;
  877.     ScreenType=SPars->Type;
  878.     SPars->Width=128; SPars->Height=64;
  879.     SPars->Type=SPars->Type|SCREENBEHIND|SCREENQUIET;
  880.     RL_Screen = (struct Screen *)OpenScreenTagList(SPars,(struct TagItem *)STags);
  881.     if(RL_Screen!=NULL) {
  882.         ScreenHeight+=(WORD)(RL_Screen->BarHeight+1);
  883.         CloseScreen(RL_Screen);
  884.     }
  885.     else {
  886.         ScreenHeight+=SCREEN_TITLE_HEIGHT;
  887.     }
  888.     SPars->Width=ScreenWidth;
  889.     SPars->Height=ScreenHeight;
  890.     SPars->Type=ScreenType;
  891.  
  892.     /* Open screen for real */
  893.     RL_Screen = (struct Screen *)OpenScreenTagList(SPars,(struct TagItem *)STags);
  894.     if(RL_Screen!=NULL) {
  895.         WPars->Screen = RL_Screen;
  896.         WPars->TopEdge=(WORD)(RL_Screen->BarHeight+1);
  897.         RL_Window = (struct Window *)OpenWindowTagList(WPars,(struct TagItem *)WTags);
  898.         if(RL_Window!=NULL) {
  899.         RL_RastPort = RL_Window->RPort;
  900.         RL_ViewPort = &(RL_Screen->ViewPort);
  901.         SetDrMd(RL_RastPort, JAM1);
  902.     /* Load palette */
  903.         if((DisplayFlags&DMODE_HAM)!=0L) {    /* Set colormap to HAM palette */
  904.             Pal8=(UBYTE *)Palette;
  905.             if(GfxBase->LibNode.lib_Version>=39) {
  906.             for(i=0;i<NumCols;i++) {
  907.                 ColR=((ULONG)*Pal8++)&0x000000ff; ColR=(ColR<<24)|(ColR<<16)|(ColR<<8)|ColR;
  908.                 ColG=((ULONG)*Pal8++)&0x000000ff; ColG=(ColG<<24)|(ColG<<16)|(ColG<<8)|ColG;
  909.                 ColB=((ULONG)*Pal8++)&0x000000ff; ColB=(ColB<<24)|(ColB<<16)|(ColB<<8)|ColB;
  910.                 SetRGB32(RL_ViewPort,(ULONG)i,ColR,ColG,ColB);
  911.             }
  912.             } else {
  913.             for(i=0;i<NumCols;i++) {
  914.                 ColR=(((ULONG)*Pal8++)&0x000000ff)>>4;
  915.                 ColG=(((ULONG)*Pal8++)&0x000000ff)>>4;
  916.                 ColB=(((ULONG)*Pal8++)&0x000000ff)>>4;
  917.                 SetRGB4(RL_ViewPort,(LONG)i,ColR,ColG,ColB);
  918.             }
  919.             }
  920.  
  921.         }
  922.         else {                    /* Set colormap to grey-scale */
  923.             if(GfxBase->LibNode.lib_Version>=39) {
  924.             for(i=0;i<NumCols;i++) {
  925.                 ColR=(0x000000ff*i)/NumCols;
  926.                 ColR=(ColR<<24)|(ColR<<16)|(ColR<<8)|ColR;
  927.                 SetRGB32(RL_ViewPort,(ULONG)i,ColR,ColR,ColR);
  928.             }
  929.             } else {
  930.             for(i=0;i<NumCols;i++) {
  931.                 ColR=(0x000000f*i)/NumCols;
  932.                 SetRGB4(RL_ViewPort,(LONG)i,ColR,ColR,ColR);
  933.             }
  934.             }
  935.         }
  936.         }
  937.         else {
  938.         RL_RastPort = NULL;
  939.         fprintf(textoutput,MyCatalogs[Language][CTXT_WINERR]);
  940.         CurrentDisplayType = DISPLAY_NONE;
  941.         CloseScreen(RL_Screen);
  942.         RL_Screen = NULL; RL_Window = NULL;
  943.         }
  944.     }
  945.     else {
  946.         fprintf(textoutput,MyCatalogs[Language][CTXT_SCRNERR]);
  947.         CurrentDisplayType = DISPLAY_NONE;
  948.         RL_Screen = NULL; RL_Window = NULL;
  949.     }
  950. }
  951.  
  952.  
  953. /***************************************************************
  954.  *
  955.  *    CloseAmigaScreen()
  956.  *
  957.  ***************************************************************/
  958.  
  959. void CloseAmigaScreen(void)
  960. {
  961.     CurrentDisplayType = DISPLAY_NONE;
  962.     if(RL_Window!=NULL) {
  963.         if(RL_Window->MenuStrip)
  964.             ClearMenuStrip(RL_Window);    /* Remove menu  */
  965.         CloseWindow(RL_Window);            /* Close window */
  966.         RL_Window = NULL;
  967.     }
  968.     if(RL_Screen!=NULL) {
  969.         CloseScreen(RL_Screen);            /* Close screen */
  970.         RL_Screen = NULL;
  971.     }
  972.     if(GfxBase!=NULL) {
  973.         CloseLibrary((struct Library *)GfxBase);  /* Close graphics.library */
  974.         GfxBase = NULL;
  975.     }
  976.     if(IntuitionBase!=NULL) {
  977.         CloseLibrary((struct Library *)IntuitionBase);  /* Close intuition.library */
  978.         IntuitionBase = NULL;
  979.     }
  980. }
  981.  
  982.  
  983. /***************************************************************
  984.  *
  985.  *    RequestDisplay()
  986.  *
  987.  ***************************************************************/
  988.  
  989. #define UnwantedProps (DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_EXTRAHALFBRITE)
  990.  
  991. void RequestDisplay(struct MyDisplayInfo *mydisplayinfo)
  992. {
  993.     struct ScreenModeRequester *smr;
  994.     struct TagItem smrtags[11];
  995.  
  996.     mydisplayinfo->ModeID     = 0xffffffff;
  997.     mydisplayinfo->Depth      = NULL;
  998.     mydisplayinfo->AutoScroll = NULL;
  999.  
  1000.     if( AslBase=OpenLibrary("asl.library", 38L) ) {
  1001.         smrtags[0].ti_Tag  = ASLSM_TitleText;
  1002.         smrtags[0].ti_Data = (ULONG)MyCatalogs[Language][CTXT_DISPREQ];
  1003.         smrtags[1].ti_Tag  = ASLSM_DoDepth;
  1004.         smrtags[1].ti_Data = TRUE;
  1005.         smrtags[2].ti_Tag  = ASLSM_DoAutoScroll;
  1006.         smrtags[2].ti_Data = TRUE;
  1007.         smrtags[3].ti_Tag  = ASLSM_PropertyFlags;
  1008.         smrtags[3].ti_Data = 0L;
  1009.         smrtags[4].ti_Tag  = ASLSM_PropertyMask;
  1010.         smrtags[4].ti_Data = UnwantedProps;
  1011.         smrtags[5].ti_Tag  = ASLSM_InitialDisplayID;
  1012.         smrtags[5].ti_Data = PAL_MONITOR_ID|HAM_KEY; /* Sorry America, Europe is my home */
  1013.         smrtags[6].ti_Tag  = ASLSM_InitialDisplayWidth;
  1014.         smrtags[6].ti_Data = 200L;
  1015.         smrtags[7].ti_Tag  = ASLSM_InitialDisplayHeight;
  1016.         smrtags[7].ti_Data = 150L;
  1017.         smrtags[8].ti_Tag  = ASLSM_InitialDisplayDepth;
  1018.         smrtags[8].ti_Data = 6L;
  1019.         smrtags[9].ti_Tag  = ASLSM_InitialAutoScroll;
  1020.         smrtags[9].ti_Data = TRUE;
  1021.         smrtags[10].ti_Tag = TAG_DONE;
  1022.         if( smr = (struct ScreenModeRequester *)AllocAslRequest(ASL_ScreenModeRequest, smrtags) ) {
  1023.             if( AslRequest(smr, 0L) ) {
  1024.             mydisplayinfo->ModeID     = smr->sm_DisplayID;
  1025.             mydisplayinfo->Depth      = smr->sm_DisplayDepth;
  1026.             mydisplayinfo->AutoScroll = smr->sm_AutoScroll;
  1027.         }
  1028.         FreeAslRequest(smr);
  1029.         }
  1030.         CloseLibrary(AslBase);
  1031.     }
  1032. }
  1033.